﻿// -----------------------------------------------------------------------------
// <copyright file="Settings.cs" company="Justin Wallace Saunders">
//     Copyright (c) Microsoft Public License. All rights reserved.
// </copyright>
// <author name="Justin Wallace Saunders" email="justinsa@live.ca" />
// -----------------------------------------------------------------------------
namespace Community.Tools.Database.Builder.Task
{
    using System;
    using System.Collections.Generic;
    using Microsoft.Build.Utilities;

    /// <summary>
    /// Settings class.
    /// </summary>
    internal class Settings
    {
        /// <summary>
        /// Default database executable.
        /// </summary>
        public const string DefaultDatabaseExecutable = "sqlcmd.exe";

        /// <summary>
        /// Default database executable arguments.
        /// </summary>
        public const string DefaultDatabaseExecutableArguments = "-E -S %DatabaseServer% -i {0}";

        /// <summary>
        /// Default execution timeout.
        /// </summary>
        public const int DefaultExecutionTimeout = 3000;

        /// <summary>
        /// Default database server.
        /// </summary>
        public const string DefaultDatabaseServer = @".\SQLEXPRESS";

        /// <summary>
        /// Initializes a new instance of the Settings class.
        /// </summary>
        /// <param name="log">MSBuild Task log</param>
        /// <param name="databaseExecutable">Database executable command</param>
        /// <param name="databaseExecutableArguments">Database executable arguments</param>
        /// <param name="databaseServer">Database server</param>
        /// <param name="executionTimeout">Execution timeout</param>
        /// <param name="fileTails">Collection of file tails</param>
        /// <param name="scripts">Collection of scripts</param>
        /// <param name="substitutions">Collection of substitution pairs</param>
        public Settings(
            TaskLoggingHelper log,
            string databaseExecutable,
            string databaseExecutableArguments,
            string databaseServer,
            int executionTimeout,
            string fileTails,
            string scripts,
            string substitutions)
        {
            this.DatabaseExecutable = string.IsNullOrWhiteSpace(databaseExecutable) ? DefaultDatabaseExecutable : databaseExecutable;
            this.DatabaseExecutableArguments = string.IsNullOrWhiteSpace(databaseExecutableArguments) ? DefaultDatabaseExecutableArguments : databaseExecutableArguments;
            this.DatabaseServer = string.IsNullOrWhiteSpace(databaseServer) ? DefaultDatabaseServer : databaseServer;
            this.ExecutionTimeout = executionTimeout < DefaultExecutionTimeout ? DefaultExecutionTimeout : executionTimeout;
            this.FileTails = new List<string>();
            this.Scripts = new List<string>();
            this.Substitutions = new Dictionary<string, string>();

            this.DatabaseExecutableArguments = this.DatabaseExecutableArguments.Replace("%DatabaseServer%", this.DatabaseServer);

            if (!string.IsNullOrWhiteSpace(fileTails))
            {
                var tokens = fileTails.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string token in tokens)
                {
                    this.FileTails.Add(token);
                }
            }

            if (!string.IsNullOrWhiteSpace(scripts))
            {
                var tokens = scripts.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string token in tokens)
                {
                    this.Scripts.Add(token);
                }
            }

            this.Substitutions.Add("%DatabaseServer%", this.DatabaseServer);
            if (!string.IsNullOrWhiteSpace(substitutions))
            {
                var tokens = substitutions.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string substitution in tokens)
                {
                    var pair = substitution.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                    if (pair == null || pair.Length != 2)
                    {
                        log.LogWarning("Incorrect format for substitution value provided: {0}", substitution);
                        continue;
                    }

                    this.Substitutions.Add(pair[0], pair[1]);
                }
            }
        }

        /// <summary>
        /// Gets or sets the database executable.
        /// </summary>
        public string DatabaseExecutable { get; set; }

        /// <summary>
        /// Gets or sets the database executable arguments.
        /// </summary>
        public string DatabaseExecutableArguments { get; set; }

        /// <summary>
        /// Gets or sets the database server.
        /// </summary>
        public string DatabaseServer { get; set; }

        /// <summary>
        /// Gets or sets the execution timeout.
        /// </summary>
        public int ExecutionTimeout { get; set; }

        /// <summary>
        /// Gets or sets the list of file tails to pre-process against.
        /// </summary>
        public IList<string> FileTails { get; private set; }

        /// <summary>
        /// Gets or sets the list of script files.
        /// This value is mandatory.
        /// </summary>
        public IList<string> Scripts { get; private set; }

        /// <summary>
        /// Gets the set of substitution key-value pairs.
        /// </summary>
        public IDictionary<string, string> Substitutions { get; private set; }
    }
}